using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using Nirvana.Common;
using UnityEngine;

namespace Nirvana.SkillEditor
{
    public class SkillMgr : MonoSingleton<SkillMgr>
    {
        private static readonly string _jsonSkillPath = Application.dataPath + "/NirvanaToolkit/SkillEditor/Runtime/SkillJsonData/";
        
        private Dictionary<SkillName, SkillSource> _skillSources = new Dictionary<SkillName, SkillSource>();
        private List<Skill> _running = new List<Skill>();

        protected override void OnInit()
        {
            var settings = new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.All,
                NullValueHandling = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Ignore,
                ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
                PreserveReferencesHandling = PreserveReferencesHandling.Objects,
                MissingMemberHandling = MissingMemberHandling.Ignore,
                ContractResolver = new ExcludePropertiesContractResolver(new[] {"foldout"})
            };
            
            if (Directory.Exists(_jsonSkillPath))
            {
                var files = Directory.GetFiles(_jsonSkillPath, "*.json");
                foreach (var file in files)
                {
                    var json = FileUtils.Read(file);
                    if (!string.IsNullOrEmpty(json))
                    {
                        var skillSource = JsonConvert.DeserializeObject<SkillSource>(json, settings);
                        if (skillSource != null)
                        {
                            var fileName = Path.GetFileNameWithoutExtension(file);
                            if (Enum.TryParse(fileName, out SkillName skillName))
                            {
                                _skillSources.Add(skillName, skillSource);
                            }
                            else
                            {
                                Debug.LogError("加载技能数据出错，未找到对应的技能名称：" + fileName);
                            }
                        }
                    }
                }
            }
        }

        public void Execute(SkillName skillName, Entry caster, Entry target)
        {
            if (_skillSources.ContainsKey(skillName))
            {
                var skill = ObjectPool<Skill>.Get();
                skill.Init(_skillSources[skillName], caster, target);
                _running.Add(skill);
            }
        }

        protected override void Update()
        {
            var doneSkills = new List<Skill>();
            foreach (var skill in _running)
            {
                if (!skill.Running(Time.deltaTime))
                {
                    doneSkills.Add(skill);
                }
            }

            foreach (var skill in doneSkills)
            {
                _running.Remove(skill);
                ObjectPool<Skill>.Release(skill);
            }
        }
    }
}
